package org.summerframework.component.upload.file.controller;

import org.summerframework.component.security.controller.BaseController;
import org.summerframework.component.upload.DownloadInputSteam;
import org.summerframework.component.upload.FileUploadService;
import org.summerframework.core.util.UrlEncodeUtil;
import eu.medsea.mimeutil.MimeType;
import eu.medsea.mimeutil.MimeUtil2;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestParam;

@RestController
@Api(tags = "文件访问", description = "功能描述")
public class FileController extends BaseController {

    private MimeUtil2 mimeUtil2;

    @Resource
    private FileUploadService fileUploadService;

    @ApiOperation(value = "文件访问, 访问指定的压缩类型", notes = "uploadFile说明   图片: thumb 音频: MP3, WAV, AMR  视频: MP4, OGV")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "文件id", required = true, dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "uploadFile", value = "图片: thumb 音频: MP3, WAV, AMR  视频: MP4, OGV", required = true, dataType = "Long", paramType = "query")
    })
    @GetMapping("/storage/{id}/{uploadFile}")
    public ResponseEntity<InputStreamResource> file(@PathVariable("id") Long id, @PathVariable("uploadFile") String uploadFile, @RequestParam(required = false) boolean download) {
        return parse(fileUploadService.getInputSteam(id, uploadFile), download);
    }

    @ApiOperation(value = "文件访问, 源文件以id获取")
    @ApiImplicitParams(
            @ApiImplicitParam(name = "id", value = "", required = true, dataType = "Long", paramType = "query")
    )
    @GetMapping("/storage/{id}")
    public ResponseEntity<InputStreamResource> fileById(@PathVariable("id") Long id, @RequestParam(required = false) boolean download, @RequestParam(required = false) String uploadFile) {
        return parse(fileUploadService.getInputSteam(id, uploadFile), download);
    }

    @ApiOperation(value = "文件访问, 源地址")
    @GetMapping(path = {"/group*/**", "/image/**"})
    public ResponseEntity<InputStreamResource> fileById(HttpServletRequest request, HttpServletResponse response, @RequestParam(required = false) boolean download, @RequestParam(required = false) String uploadFile) {
        return parse(fileUploadService.getInputSteam(request.getServletPath(), uploadFile), download);
    }

    private ResponseEntity<InputStreamResource> parse(DownloadInputSteam fileInputSteam, boolean download) {
        HttpHeaders headers = new HttpHeaders();
        headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
        headers.add("Content-Disposition", "inline; filename*=UTF-8''" + UrlEncodeUtil.encodeURL(fileInputSteam.getFileName()).replaceAll("\\+", "%20"));
        headers.add("Pragma", "no-cache");
        headers.add("Expires", "0");
        headers.add("Last-Modified", new Date().toString());
        headers.add("ETag", String.valueOf(System.currentTimeMillis()));
        MediaType contentType;
        final List<MimeType> mimeTypes = new ArrayList<>(mimeUtil2.getMimeTypes(fileInputSteam.getFileName()));

        if (!download && mimeTypes.size() > 0) {
            contentType = MediaType.parseMediaType(mimeTypes.get(0).toString());
        } else {
            contentType = MediaType.parseMediaType("application/octet-stream");
        }

        return ResponseEntity.ok().headers(headers).contentType(contentType).body(new InputStreamResource(fileInputSteam));
    }

    @PostConstruct
    public void init() {
        mimeUtil2 = new MimeUtil2();
        mimeUtil2.registerMimeDetector("eu.medsea.mimeutil.detector.ExtensionMimeDetector");
    }
}
